# -*- coding:utf-8 -*-
import logging
import re
from datetime import datetime
from decimal import Decimal
from typing import List

from dateutil.relativedelta import relativedelta
from redis.asyncio import Redis
from sqlalchemy.ext.asyncio import AsyncSession

from exceptions.exception import ServiceException
from module_admin.dao.user_dao import UserDao
from module_admin.entity.vo.sys_table_vo import SysTablePageModel
from module_admin.entity.vo.user_vo import UserInfoModel
from module_admin.service.sys_table_service import SysTableService
from module_product.dao.bg_order_dao import BgOrderDao
from module_product.dao.bg_product_dao import BgProductDao
from module_product.dao.bg_product_price_dao import BgProductPriceDao
from module_product.entity.vo.bg_order_vo import BgOrderPageModel, BgOrderModel, BgOrderCreateModel, PhoneMsgReq
from module_vip.dao.bg_vip_dao import BgVipDao
from module_vip.entity.vo.bg_vip_vo import BgVipModel
from utils.common_util import CamelCaseUtil, export_list2excel
from utils.page_util import PageResponseModel
from utils.string_util import StringUtil


class BgOrderService:
    """
    用户管理模块服务层
    """
    logger = logging.getLogger(__name__)

    @classmethod
    async def get_bg_order_list(cls, query_db: AsyncSession, query_object: BgOrderPageModel, data_scope_sql: str) -> [list | PageResponseModel]:
        bg_order_list = await BgOrderDao.get_bg_order_list(query_db, query_object, data_scope_sql, is_page=True)
        return bg_order_list

    @classmethod
    async def get_bg_user_order_list(cls, query_db: AsyncSession,  page_query: BgOrderPageModel, user_id: int) -> [list | PageResponseModel]:
        page_query.user_id = user_id
        bg_order_list = await BgOrderDao.get_bg_order_list(query_db, page_query, None, is_page=True)
        return bg_order_list

    @classmethod
    async def get_bg_order_by_id(cls, query_db: AsyncSession, bg_order_id: int) -> BgOrderModel:
        bg_order = await  BgOrderDao.get_by_id(query_db, bg_order_id)
        bg_order_model = BgOrderModel(**CamelCaseUtil.transform_result(bg_order))
        return bg_order_model



    @classmethod
    async def add_bg_order(cls, query_db: AsyncSession, redis:Redis, query_object: BgOrderCreateModel, user: UserInfoModel) -> BgOrderModel:
        product = await BgProductDao.get_by_id(query_db, query_object.product_id)

        prices = await BgProductPriceDao.get_bg_product_prices_by_product_id(query_db, query_object.product_id)
        if product is None:
            raise ServiceException(message='产品不存在')
        index = await redis.incr(f"price_index_{product.id}")
        real_price = prices[(index - 1) % len(prices)]

        create_order = BgOrderModel(
            product_id=product.id,
            product_month=product.month,
            product_name=product.name,
            product_pay=real_price.random_price,
            product_price=product.price,
            pay_wx_code=real_price.image_url,
            order_no=StringUtil.generate_order_number(),

            create_by=user.user_id,
            dept_id=user.dept_id,
            user_id=user.user_id,
            user_name=user.user_name,
            user_phone=user.phonenumber
        )

        bg_order_model = await BgOrderDao.add_bg_order(query_db, create_order)
        return bg_order_model


    @classmethod
    async def update_bg_order(cls, query_db: AsyncSession, query_object: BgOrderModel) -> BgOrderModel:
        bg_order = await BgOrderDao.edit_bg_order(query_db, query_object)
        bg_order_model = BgOrderModel(**CamelCaseUtil.transform_result(bg_order))
        return bg_order_model


    @classmethod
    async def del_bg_order(cls, query_db: AsyncSession, bg_order_ids: List[str]):
        await BgOrderDao.del_bg_order(query_db, bg_order_ids)


    @classmethod
    async def export_bg_order_list(cls, query_db: AsyncSession, query_object: BgOrderPageModel, data_scope_sql) -> bytes:
        bg_order_list = await BgOrderDao.get_bg_order_list(query_db, query_object, data_scope_sql, is_page=False)
        filed_list = await SysTableService.get_sys_table_list(query_db, SysTablePageModel(tableName='bg_order'), is_page=False)
        filtered_filed = sorted(filter(lambda x: x["show"] == '1', filed_list), key=lambda x: x["sequence"])
        new_data = []
        for item in bg_order_list:
            mapping_dict = {}
            for fild in filtered_filed:
                if fild["prop"] in item:
                    mapping_dict[fild["label"]] = item[fild["prop"]]
            new_data.append(mapping_dict)
        binary_data = export_list2excel(new_data)
        return binary_data

    @classmethod
    async def get_order_statistics(cls, query_db: AsyncSession) -> dict:
        """
        获取订单统计信息
        """
        statistics = await BgOrderDao.get_order_statistics(query_db)
        return statistics

    @classmethod
    async def receive_pay_msg(cls, query_db: AsyncSession, msg_model: PhoneMsgReq):
        cls.logger.info(msg_model)
        pattern = re.compile(r"(\d+(?:\.\d+)?)元")
        match = pattern.search(msg_model.msg_content)
        if match:
            amount_yuan = Decimal(match.group(1))
            amount_cents = int(amount_yuan * 100)
            orders = await BgOrderDao.get_by_product_pay(query_db, amount_cents)
            if orders and len(orders) > 0:
                order = orders[0]
                # 保存订单状态
                order.status = '1'
                await query_db.flush()
                vip_user = await BgVipDao.get_by_user_id(query_db, order.user_id)
                if vip_user is None:
                    # 创建vip信息
                    user = await UserDao.get_user_by_name(query_db, order.user_name)
                    vip_model = BgVipModel(
                        dept_id=user.dept_id,
                        create_by=user.user_id,
                        user_id=order.user_id,
                        begin_date=datetime.now(),
                        end_date=datetime.now() + relativedelta(months=order.product_month),
                        status='1',
                        count=1,
                        total_amount=amount_cents
                    )
                    await BgVipDao.add_bg_vip(query_db, vip_model, auto_commit=False)
                else:
                    # 修改状态和套餐时间
                    vip_user.status = '1'
                    if vip_user.end_date < datetime.now():
                        vip_user.begin_date = datetime.now()
                        vip_user.end_date = datetime.now() + relativedelta(months=order.product_month)
                    else:
                        vip_user.end_date = vip_user.end_date + relativedelta(months=order.product_month)
                    await query_db.flush()
                # 处理推广返利
                from module_user.service.bg_user_affiliate_service import BgUserAffiliateService
                affiliate_service = BgUserAffiliateService()
                await affiliate_service.process_order_commission(query_db, order.id, order.user_id, amount_yuan, auto_commit=False)
                
                await query_db.commit()
